package utils

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

// Git - git info
type Git struct {
	basePath string

	Git    string
	Branch string
	Tag    string

	Head string
}

func run(g Git, cmd *exec.Cmd) error {
	cmd.Dir = g.basePath
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	return cmd.Run()
}

func runGroup(g Git, cmds []*exec.Cmd) error {
	for _, v := range cmds {
		err := run(g, v)
		if err != nil {
			fmt.Println(err)
			return err
		}
	}
	return nil
}

// Execute - execute git order
func (g Git) Execute(orders ...[]string) (int, error) {
	for i, order := range orders {
		cmd := "git"
		for _, o := range order {
			cmd += " " + o
		}
		fmt.Println("> " + cmd)
		err := run(g, exec.Command("git", order...))
		fmt.Println("< " + cmd)
		if err != nil {
			fmt.Println(err)
			return i, err
		}
	}
	return -1, nil
}

// News - init git info
func (g Git) News(config Config) Git {
	// fmt.Println(config.Prog)
	// fmt.Println(config.BasePath)
	// fmt.Println(config.Etc)
	g.basePath = config.BasePath

	g.Git = filepath.Join(g.basePath, ".git")
	g.Branch = filepath.Join(g.basePath, ".git/refs/heads")
	g.Tag = filepath.Join(g.basePath, ".git/refs/tags")

	g.Head = filepath.Join(g.basePath, ".git/HEAD")

	return g
}

// ThisBranch - return this branch
func (g Git) ThisBranch() (string, error) {
	f, err := os.Open(g.Head)
	if err != nil {
		return "", err
	}
	defer f.Close()
	br := bufio.NewReader(f)
	a, _, _ := br.ReadLine()
	link := strings.Split(string(a), " ")[1]
	return filepath.Base(link), nil
}

// Branches - return all branches
func (g Git) Branches() ([]string, error) {
	list, err := ioutil.ReadDir(g.Branch)
	if err != nil {
		return []string{}, err
	}
	return getFileName(list), nil
}

// Tags - return all tags
func (g Git) Tags() ([]string, error) {
	list, err := ioutil.ReadDir(g.Tag)
	if err != nil {
		return []string{}, err
	}
	return getFileName(list), nil
}

func getFileName(list []os.FileInfo) []string {
	var ans []string
	for _, v := range list {
		ans = append(ans, v.Name())
	}
	return ans
}

// -------------------------------

/*
// Pull - do git pull
func (g Git) Pull() error {
	var err error
	fmt.Println("[git pull start]")
	run(g, exec.Command("git", "fetch"))
	b, err := g.Branches()
	if err != nil {
		return err
	}
	for _, v := range b {
		runGroup(g, []*exec.Cmd{
			// exec.Command("git", "branch", "--set-upstream-to=origin/"+v, v),
			exec.Command("git", "pull", "origin", v+":"+v),
		})
	}
	fmt.Println("[git pull finish]")
	return nil
}
*/
